﻿using SuperX.Common;
using SuperX.Common.BasicService;
using SuperX.Common.Log;
using SuperX.Common.Object;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;

namespace SuperX.ProjectCore
{
    /// <summary>
    /// 项目类
    /// </summary>    
    public class ProjService : BasicObject, IProjService, IBasicObject, IJsonSerialize, INotifyPropertyChanged, IDisposable, ICloneable
    {
        // 
        public event EventHandler<ExceptionArgs> Error;

        // 
        public string Version
        {
            get
            {
                return "1.0.0";
            }
        }

        // 
        public IProject Project { get; private set; }

        // 
        public ServiceRunMode RunMode { get; private set; }

        // 
        private ProjService()
        {
            this.Name = "IOTCoreService";
            this.RunMode = ServiceRunMode.Runtime;
        }

        // 
        public void SetRunMode(ServiceRunMode runMode)
        {
            this.RunMode = runMode;
        }

        // 
        public static ProjService GetInstance(bool isNewInstance = false)
        {
            if (isNewInstance)
            {
                return new ProjService();
            }
            object instanceLock;
            if (ProjService.ServerHostInstance != null)
            {
                instanceLock = ProjService.InstanceLock;
                lock (instanceLock)
                {
                    return ProjService.ServerHostInstance;
                }
            }
            instanceLock = ProjService.InstanceLock;
            ProjService serverHostInstance;
            lock (instanceLock)
            {
                if (ProjService.ServerHostInstance != null)
                {
                    serverHostInstance = ProjService.ServerHostInstance;
                }
                else
                {
                    ProjService.ServerHostInstance = new ProjService();
                    BasicServiceManager.SetServerHost(ProjService.ServerHostInstance);
                    serverHostInstance = ProjService.ServerHostInstance;
                }
            }
            return serverHostInstance;
        }

        // 
        public static void Exit()
        {
            if (ProjService.ServerHostInstance == null)
            {
                return;
            }
            object instanceLock = ProjService.InstanceLock;
            lock (instanceLock)
            {
                ProjService.ServerHostInstance.Dispose();
                ProjService.ServerHostInstance = null;
            }
        }

        // 
        public IProject CreateProjectByTemplate(string projectName, string description, string projectPath, string template)
        {
            string path = string.Format("{0}.sprojtpl", template);
            string text = Path.Combine("Template", path);
            if (string.IsNullOrWhiteSpace(template) || !File.Exists(text))
            {
                return null;
            }
            ProjectInfo projectInfo = ProjectInfo.CreateProjectByTemplate(projectName, description, text);
            if (projectInfo == null)
            {
                this.NotifyError(new Exception("项目创建失败"), false);
                return null;
            }
            this.Project = new Project(this)
            {
                ProjectInfo = projectInfo
            };
            ((Project)this.Project).ProjectFullPath = Path.GetFullPath(projectPath);
            ((Project)this.Project).ProjectDir = Path.GetDirectoryName(this.Project.ProjectFullPath);
            ((Project)this.Project).LoadPlugIns();
            this.SaveProject();
            return this.Project;
        }

        // 
        public IProject CreateProject(string projectName, string description, string projectPath, string plugIns)
        {
            ProjectInfo projectInfo = string.IsNullOrWhiteSpace(plugIns) ? ProjectInfo.CreateDefaultProject(projectName, description) : ProjectInfo.CreateProject(projectName, description, plugIns);
            if (projectInfo == null)
            {
                this.NotifyError(new Exception("项目创建失败"), false);
                return null;
            }
            this.Project = new Project(this)
            {
                ProjectInfo = projectInfo
            };
            ((Project)this.Project).ProjectFullPath = Path.GetFullPath(projectPath);
            ((Project)this.Project).ProjectDir = Path.GetDirectoryName(this.Project.ProjectFullPath);
            ((Project)this.Project).LoadPlugIns();
            this.SaveProject();
            return this.Project;
        }

        //
        public IProject LoadProject(string projectPath)
        {
            this.Project = new Project(this);
            if (!this.Project.Load(projectPath))
            {
                this.Project.Dispose();
                this.Project = null;
            }
            return this.Project;
        }

        // 
        public void SaveProject()
        {
            if (this.Project == null)
            {
                return;
            }
            if (!this.Project.Save())
            {
                this.NotifyError(new Exception("保存项目失败，请重试！"), false);
            }
        }

        // 
        public void CloseProject()
        {
            if (this.Project == null)
            {
                return;
            }
            this.Project.Dispose();
            BasicServiceManager.SetCurrentProject(string.Empty);
            this.Project = null;
        }

        // 
        public void NotifyError(Exception error, bool isExitProject = false)
        {
            Logger.ErrorException(error);
            EventHandler<ExceptionArgs> error2 = this.Error;
            if (error2 != null)
            {
                error2(this, new ExceptionArgs(error));
            }
            if (isExitProject)
            {
                IProject project = this.Project;
                if (project == null)
                {
                    return;
                }
                project.Dispose();
            }
        }

        // 
        public void NotifyExit()
        {
            Logger.Error("通知强制退出服务");
            IProject project = this.Project;
            if (project != null)
            {
                project.Dispose();
            }
            Process.GetCurrentProcess().Kill();
        }

        // 
        public override void Dispose()
        {
            if (this.Project != null)
            {
                this.Project.Dispose();
                this.Project = null;
            }
            base.Dispose();
        }

        //
        public static ProjService ServerHostInstance;

        // 
        private static readonly object InstanceLock = new object();
    }
}
